<template>
  <div>
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="40%"
      @close="closeDialog"
    >
      <el-form
        :model="taskFormData"
        ref="taskFormRef"
        :rules="taskRules"
        label-width="100px"
        :inline="false"
        size="default"
      >
        <el-form-item label="任务名" prop="name">
          <el-input v-model="taskFormData.name"></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="taskFormData.taskDescription"></el-input>
        </el-form-item>
        <el-form-item label="执行项目" prop="project">
          <el-select
            v-model="taskFormData.project"
            value-key="id"
            placeholder="请选择项目"
            clearable
            filterable
            @change="selectProject"
          >
            <el-option
              v-for="project in projectList"
              :key="project.id"
              :label="project.name"
              :value="project"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="cron表达式" prop="cronExpression">
          <el-input v-model="taskFormData.cronExpression"></el-input>
        </el-form-item>
      </el-form>

      <template #footer>
        <span>
          <el-button @click="closeDialog">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确认</el-button>
        </span>
      </template>
    </el-dialog>

    <el-card
      shadow="always"
      style="margin: 2px 5px"
      :body-style="{
        padding: '20px',
        height: 'calc(100vh - 170px)',
        'overflow-y': 'auto',
      }"
    >
      <template #header>
        <el-row :gutter="20">
          <el-col :span="12" :offset="0"
            ><span class="card-title"> 定时任务设置</span></el-col
          >
          <el-col :span="12" :offset="0">
            <div style="float: right">
              <el-button
                type="success"
                :icon="Plus"
                size="default"
                @click="openTaskAdder"
                >新增</el-button
              >
            </div>
          </el-col>
        </el-row>
      </template>

      <el-table :data="showSunnyQuartzTaskList" border stripe max-height="800">
        <el-table-column type="index" width="50" />
        <el-table-column prop="name" label="任务名"> </el-table-column>
        <el-table-column prop="taskDescription" label="描述"> </el-table-column>
        <el-table-column prop="cronExpression" label="cron表达式">
        </el-table-column>
        <el-table-column label="执行自动化项目" prop="project.name">
        </el-table-column>
        <el-table-column label="启动" width="60">
          <template #default="{ row }">
            <el-switch
              v-model="row.isActive"
              size="small"
              @change="updateQuartzTask(row)"
            >
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-button
              type="primary"
              size="default"
              :icon="EditPen"
              @click="handleEdit(row)"
              >编辑</el-button
            >
            <el-button
              type="danger"
              size="default"
              :icon="Delete"
              @click="deleteQuartzTask(row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        style="margin-top: 10px"
        background
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50]"
        layout="total,prev,sizes, pager, next,jumper"
        :total="allShowSunnyQuartzTaskList.length"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { Plus, EditPen, Delete } from "@element-plus/icons-vue";
import { ref, onMounted, computed } from "vue";
import type { SunnyQuartzTask } from "@/types/sunnyQuartzTask/type";
import {
  addSunnyQuartzTaskApi,
  deleteSunnyQuartzTaskApi,
  listSunnyQuartzTasksApi,
  updateSunnyQuartzTaskApi,
} from "@/api/sunnyQuartzTask";
import { ElForm, type FormInstance, type FormRules } from "element-plus";
import type { SunnyProject } from "@/types/sunnyProject/type";
import { listProjectsApi } from "@/api/sunnyproject";

const sunnyQuartzTaskList = ref<SunnyQuartzTask[]>([]);

const projectList = ref<SunnyProject[]>([]);

interface ShowSunnyQuartzTask extends SunnyQuartzTask {
  project: SunnyProject;
}
/**
 * 通过计算属性为sunnyQuartzTask对象通过projectId补充project信息，以在下拉框选择和表格展示中显示项目名而非项目id。
 */
const allShowSunnyQuartzTaskList = computed(() => {
  return sunnyQuartzTaskList.value.map((task) => {
    //在projectList中通过task的projectId找到这个project对象。
    let project = projectList.value.find((project) => {
      return project.id === task.projectId;
    });
    //解构赋值，将task中的所有字段再加一个project作为要存储的数据对象放到数组里。
    return {
      ...task,
      project,
    };
  });
});

/**
 * 选中项目时，选中的v-model是project对象，所以在选中时，为projectId赋值
 * @param project 选中的项目
 */
function selectProject(project: SunnyProject) {
  taskFormData.value.projectId = project.id;
}

//新增和修改表单弹窗
const dialogTitle = ref("");
const dialogVisible = ref(false);

const taskFormRef = ref<FormInstance>();
const taskRules = ref<FormRules>({
  name: [{ required: true, message: "请输入任务名", trigger: "blur" }],
  project: [
    { required: true, message: "请选择要执行的项目", trigger: "change" },
  ],
  cronExpression: [
    { required: true, message: "请填写定时表达式", trigger: "blur" },
  ],
});
const taskFormData = ref<ShowSunnyQuartzTask>({
  id: 0,
  name: "",
  taskDescription: "",
  cronExpression: "",
  //为了让select显示的时候，能够在未选中的时候显示请选择而不是一个数字，所以用null。
  projectId: null,
  project: {} as SunnyProject,
  isActive: true,
});

//关闭弹窗时重置内容和校验结果
function closeDialog() {
  dialogVisible.value = false;
  taskFormRef.value?.resetFields();
  taskFormRef.value?.clearValidate();
}

//提交时根据id是否为0，选择新增或者修改任务
function handleSubmit() {
  taskFormRef.value?.validate((valid) => {
    if (valid) {
      if (taskFormData.value.id) {
        updateQuartzTask(taskFormData.value);
      } else {
        addQuartzTask(taskFormData.value);
      }
      closeDialog();
    }
  });
}

//初始化获取任务和项目列表
onMounted(() => {
  listTasks();
  listProjects();
});

/**
 * 获取task列表
 */
function listTasks() {
  listSunnyQuartzTasksApi().then(({ data }) => {
    sunnyQuartzTaskList.value = data;
  });
}

/**
 * 获取项目列表
 */
function listProjects() {
  listProjectsApi().then(({ data }) => {
    projectList.value = data;
  });
}

/**
 * 打开新增任务窗口
 */
function openTaskAdder() {
  dialogVisible.value = true;
  dialogTitle.value = "新增定时任务";
  taskFormData.value = {
    id: 0,
    name: "",
    taskDescription: "",
    cronExpression: "",
    projectId: null,
    project: {} as SunnyProject,
    isActive: true,
  };
}

/**
 * 打开编辑任务窗口
 * @param task 编辑的任务
 */
function handleEdit(task: ShowSunnyQuartzTask) {
  dialogTitle.value = "修改定时任务";
  dialogVisible.value = true;
  taskFormData.value = { ...task };
}

/**
 * 完成任务添加
 * @param task 添加的任务
 */
function addQuartzTask(task: SunnyQuartzTask) {
  addSunnyQuartzTaskApi(task).then(() => {
    listTasks();
  });
}

/**
 * 删除任务方法
 * @param task 删除的任务
 */
function deleteQuartzTask(task: SunnyQuartzTask) {
  deleteSunnyQuartzTaskApi(task.id).then(() => {
    listTasks();
  });
}

/**
 * 更新任务方法，不管是编辑任务信息更新还是开关任务都通过这个方法调用完成。
 * @param task 更新的任务
 */
function updateQuartzTask(task: SunnyQuartzTask) {
  updateSunnyQuartzTaskApi(task).then(() => {
    listTasks();
  });
}

//分页功能
const currentPage = ref(1);
const pageSize = ref(10);
function handleSizeChange(size: number) {
  pageSize.value = size;
}

const handleCurrentChange = (cp: number) => {
  currentPage.value = cp;
};

const showSunnyQuartzTaskList = computed(() => {
  //分页实际上就是算出来当前列表中，下标为多少范围的数据需要展示
  //第1页   下标0-9  第2页 10-19    // 20页第1页   下标 0-19
  let startIndex = (currentPage.value - 1) * pageSize.value;
  let endIndex = currentPage.value * pageSize.value - 1;

  let index = -1;
  let currentPageData = allShowSunnyQuartzTaskList.value.filter(() => {
    index += 1;
    return index <= endIndex && index >= startIndex;
  });
  return currentPageData;
});
</script>

<style scoped></style>
